﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CPPEI.Coolzon.DisplayApp
{
    class PerformanceMonitorThread
    {
        private bool _isRunning = true;
        private Thread _thread;
        private EventWaitHandle _waitHandle;
        private DateTime _lastExeTime = DateTime.Now;

        //获取当前进程对象
        Process _cur;

        PerformanceCounter _curpcp;
        PerformanceCounter _curpc;
        PerformanceCounter _curtime;
        PerformanceCounter _totalcpu;

        /// <summary>
        /// cpu数量
        /// </summary>
        int ProcesserCount = 0;

        const int MB_DIV = 1024 * 1024;

        public void Start()
        {
            if (_thread == null)
            {
                ProcesserCount = Environment.ProcessorCount;

                _cur = Process.GetCurrentProcess();

                _curpcp = new PerformanceCounter("Process", "Working Set - Private", _cur.ProcessName);
                _curpc = new PerformanceCounter("Process", "Working Set", _cur.ProcessName);
                _curtime = new PerformanceCounter("Process", "% Processor Time", _cur.ProcessName);
                _totalcpu = new PerformanceCounter("Processor", "% Processor Time", "_Total");

                _thread = new Thread(Running);
                _thread.Name = "PerformanceMonitorThread";
                _isRunning = true;
                _waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
                _thread.Start();
            }
        }

        public void Stop()
        {
            if (_thread != null)
            {
                _isRunning = false;

                _waitHandle.WaitOne();
                _thread = null;
            }
        }

        private void Running()
        {
            while (_isRunning)
            {
                double privateWorkSet = _curpcp.NextValue() / MB_DIV;
                double cpuPreTime = _curtime.NextValue() / ProcesserCount;
                Event.UI.UIEventBus.PublishAsync(new Event.UI.UIPerformanceMonitorReportEvent(privateWorkSet,
                    _curpc.NextValue(),
                    cpuPreTime,
                    _totalcpu.NextValue()));

                if (privateWorkSet > 700 && (DateTime.Now.Ticks - _lastExeTime.Ticks > TimeSpan.FromSeconds(30).Ticks))
                {
                    ClearMemory();
                    _lastExeTime = DateTime.Now;
                }
                Thread.Sleep(1000);
            }
            _waitHandle.Set();
        }
        [System.Runtime.InteropServices.DllImport("psapi.dll")]
        static extern int EmptyWorkingSet(IntPtr hwProc);
        private static void ClearMemory()
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
            try
            {
                EmptyWorkingSet(System.Diagnostics.Process.GetCurrentProcess().Handle);
            }
            catch (Exception ex)
            {
                Common.Logger.Error(ex.Message);
            }
        }
    }
}

